//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//------------------------------------------------------------------------------
//
//  File:  clock.h
//  Programmer: Visual.Wei (2007)
//
//  This file specifies clock module interface. It controls CLKM
//  hardware modules.
//
#ifndef __CLOCK_H_
#define __CLOCK_H_
#include <s3c2443.h>
#include <CSync.h>

//------------------------------------------------------------------------------
//
//  Enum:  CLK_CLOCK
//
//  This enumeration define different clock sources. It is used in internal
//  structures to specify device clock.
//
typedef enum {
    CLK_CLOCK_INVALID = 0 ,     // INVALID CLOCK
    CLK_CLOCK_ARMWDT,           // internal watchdog clock
    CLK_CLOCK_ARMXOR,           // external reference peripheral clock
    CLK_CLOCK_ARMPER,           // external peripheral clock
    CLK_CLOCK_LCD,              // LCD controller
    CLK_CLOCK_MPUI,             // MPUI port interface
    CLK_CLOCK_TIM,              // MPU internal timer clock
	//7
    CLK_CLOCK_EAC12M_PLL,       // EAC12M PLL
    CLK_CLOCK_MMC_PLL,          // MMC PLL
    CLK_CLOCK_UART2_PLL,        // UART2 PLL
    CLK_CLOCK_UART1_PLL,        // UART1 PLL
    CLK_CLOCK_USBO_PLL,         // USB OTG PLL
    CLK_CLOCK_CAM_PLL,          // CAM PLL
    CLK_CLOCK_MCBSP1_PLL,       // MCBSP1 PLL
    CLK_CLOCK_USBD_PLL,         // USB device PLL
    CLK_CLOCK_USBH_PLL,         // USB host PLL
    CLK_CLOCK_MCBSP2_PLL,       // MCBSP2 PLL
    //17
    CLK_CLOCK_AC97,
    CLK_CLOCK_TSADC,
    CLK_CLOCK_SDMMC,
    CLK_CLOCK_PWM,
    CLK_CLOCK_UART0,
    CLK_CLOCK_UART1,
    CLK_CLOCK_UART2,  
    CLK_CLOCK_UART3,    
    CLK_CLOCK_SPIHS,
    CLK_CLOCK_SPI0,
    CLK_CLOCK_SPI1,
    CLK_CLOCK_I2C,
    CLK_CLOCK_GPIO,
    CLK_CLOCK_WDT,
    CLK_CLOCK_RTC,
    CLK_CLOCK_I2S,
    //33
    CLK_CLOCK_CAMIF,
    CLK_CLOCK_HSMMC,
    CLK_CLOCK_USBD,
    CLK_CLOCK_USBH,
    CLK_CLOCK_CF,
    //
    CLK_CLOCK_USBH_EPLL,

    CLK_CLOCK_DMA0,
    CLK_CLOCK_DMA1,
    CLK_CLOCK_DMA2,
    CLK_CLOCK_DMA3,
    CLK_CLOCK_DMA4,
    CLK_CLOCK_DMA5,    

    CLK_CLOCK_SIZE
} CLK_CLOCK;

typedef enum {
    CLOCK_ALLOCATION_ID_REGISTER_ACCESS = 0,
    CLOCK_ALLOCATION_ID_OPERATION,
    CLOCK_ALLOCATION_OTHER,
    CLOCK_ALLOCATION_SIZE
} CLOCK_ALLOCATION ;

//------------------------------------------------------------------------------
//
//  Type:  CLK_DEVICE_CLOCKS
//
//  This structure is used to specify clocks required by device. The device is
//  specified by base registry address.
//
typedef struct
{
	DWORD base;
	ULONG count;
	const CLK_CLOCK *pClockId;
}
CLK_DEVICE_CLOCKS;

class S3c2443Clock
{
public:
	S3c2443Clock();
	~S3c2443Clock();
	BOOL Init()
	{
		return (m_pCLKMRegs!=NULL );
	};
	CLK_CLOCK AllocateClock(DEVICE_LOCATION *pDevLoc, CLOCK_ALLOCATION clockID) ;
	BOOL FreeClock(CLK_CLOCK clockItem) ;
	BOOL RequestClock(CLK_CLOCK id);
	BOOL ReleaseClock( CLK_CLOCK id);
protected:
	CLockObject m_CS;
	S3C2443_CLKPWR_REG *m_pCLKMRegs;
	DWORD m_ClockRef[CLK_CLOCK_SIZE];
	BOOL EnableClock(CLK_CLOCK id);
	BOOL DisableClock(CLK_CLOCK id);
	BOOL PowerUp();
	BOOL PowerDown();
private:
	UINT32 hclock;
	UINT32 pclock;
	UINT32 sclock;
};

//------------------------------------------------------------------------------

#endif

